package lacus.wd_cinema.handler;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lacus.wd_cinema.exception.UnauthorizedException;
import lacus.wd_cinema.exception.EntityNotFoundException;
import lacus.wd_cinema.exception.OperationNotAllowedException;
import lacus.wd_cinema.exception.ValidationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.io.IOException;

/**
 * 全局错误捕获类
 * @author lacus
 * @version 0.5
 * @since 0.4
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 捕获 Spring Validation 中的验证错误
     * @param ex 捕获到的错误
     * @return 400响应
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<String> handleConstraintViolationException(
            ConstraintViolationException ex) {
        ConstraintViolation<?> firstViolation = ex.getConstraintViolations().iterator().next();
        String message = firstViolation.getMessage();
        return ResponseEntity.badRequest().body(message);
    }

    /**
     * 捕获自定义验证（通常对于字段唯一性要求的检查）的错误
     * @param ex 捕获到的错误
     * @return 400响应
     */
    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<String> handleValidationException(
            ValidationException ex) {
        return ResponseEntity.badRequest().body(ex.getMessage());
    }

    /**
     * 捕获操作被阻止的错误
     * @param ex 捕获到的错误
     * @return 409响应
     */
    @ExceptionHandler(OperationNotAllowedException.class)
    public ResponseEntity<String> handleOperationNotAllowedException(
            OperationNotAllowedException ex) {
        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
    }

    /**
     * 捕获未找到实体的错误
     * @param ex 捕获到的错误
     * @return 404响应
     */
    @ExceptionHandler(EntityNotFoundException.class)
    public ResponseEntity<String> handleEntityNotFoundException(
            EntityNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }

    /**
     * 捕获用户未授权错误，令其重定向到登录页面
     * @param ignoredEx 捕获到的错误
     */
    @ExceptionHandler(UnauthorizedException.class)
    public void handleUnauthorizedException(
            UnauthorizedException ignoredEx,
            HttpServletResponse response) throws IOException {
        response.sendRedirect("/login");
    }
}
